#ifndef GAMEENGINE_MULTIMEDIA_MUSIC_H
#define GAMEENGINE_MULTIMEDIA_MUSIC_H

#include <GameEngine/Multimedia/multimedia_settings.h>

#include <GameEngine/Core/Classes/rtti.h>
#include <GameEngine/Core/Resource/resource.h>
#include <GameEngine/Core/Resource/ptr_resource.h>
#include <GameEngine/Core/string.h>

#include <QtCore/QObject>

#include <libzplay/libzplay.h>



#ifdef GAMEENGINE_NAMESPACES
namespace GameEngine {
#endif

//========================================================


//! Allocates music data
/*!
 *  This allocator allocates data for the libZPlay music player 
 */
class AllocatorMusic {

public:
	static libZPlay::ZPlay* allocate(unsigned int nb_elements);
	static void desallocate(libZPlay::ZPlay* item, unsigned int nb_elements);
};


//========================================================


//! Implements a music player
/*!
 *  The music player can be seen as a wrapper to the libZPlay third party library. It
 *  allows several basic operations, e.g., start/pause/stop a music or change the volume
 *  at which music is played.
 *
 *  Musics are handled as resources, which means that several Music instances can share the
 *  same internal music player. Any change performed by any of the Music instances will thus
 *  affect all the other Music instances. The internal music player will not be destroyed as
 *  long as at least one music instance is using it.
 *
 *  If you need to be notified of changes occuring to the music player, say, when the
 *  currently played music is finished, please use the MusicObserver class, which can
 *  observe the state of a music player. See the MusicObserver class documentation for
 *  more information about this mechanism.
 */
class _Multimedia_decl Music : public QObject, public PtrResource<libZPlay::ZPlay,AllocatorMusic> {
	GAMEENGINE_DECLARE_RTTI_SINGLE(Music)
	Q_OBJECT
	//! The resource manager class is friend of the music class because it must be able to access its ID and context
	friend class ResourceManager<ID,CONTEXTID>;

public:
	//! Typedef used for convenient manipulation of the music resource type
	typedef PtrResource<libZPlay::ZPlay,AllocatorMusic> RESOURCE_TYPE;
	//! Typedef for music resource managers
	typedef ResourceManager<ID,CONTEXTID> MusicResourceManager;

public:
	//! Enumerates possible states of the music player
	enum PlayerState {
		//! Music is currently being played
		Playing,
		//! Music is currently paused
		Paused,
		//! Music is currently stopped
		Stopped,
		//! Music is currently invalid
		Invalid
	};

	Music();
	Music(const GEString& file);
	Music(const Music& rhs);
	Music& operator=(const Music& rhs);
	virtual ~Music();

	bool play() const;
	bool resume() const;
	bool pause() const;
	bool stop() const;

	bool set_file(const GEString& file) const;
	bool set_volume(int volume) const;

	PlayerState state() const;

protected:
	virtual CONTEXTID context() const;
};



//========================================================


#ifdef GAMEENGINE_NAMESPACES
} // namespace GameEngine
#endif

#endif
